package cn.shiwei.hr.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

import static cn.shiwei.hr.constants.MessageConstants.*;

/**
 * rabbitMQ的配置类, 用于获取交换机, 队列, 绑定队列交换机
 * 定义了RabbitTemplate 指定 JSON转换器
 */
@Configuration
public class RabbitMQConfig {

    /**
     * 创建交换机, 注册到spring容器
     * @return 返回交换机
     */
    @Bean
    public Exchange exchangeKillTopic(){
        // 创建名为: EXCHANGE_KILL_TOPIC 的交换机, 设置为需要持久化
        return ExchangeBuilder.topicExchange(EXCHANGE_KILL_TOPIC).durable(true).build();
    }

    /**
     * 定义延迟队列
     * @return
     */
    @Bean
    public Queue delayQueue(){
        Map<String, Object> args = new HashMap<>(2);
        // x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", EXCHANGE_KILL_TOPIC);
        // x-dead-letter-routing-key  这里声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", "#.dead");
        // x-message-ttl  声明队列的TTL
        args.put("x-message-ttl", 5000);
        return QueueBuilder.durable(QUEUE_DELAY).withArguments(args).build();
    }

    /**
     * 定义死信队列
     * @return
     */
    @Bean
    public Queue deadQueue(){
        return QueueBuilder.durable(QUEUE_DEAD).build();
    }

    // 绑定延迟队列到交换机
    @Bean
    public Binding delayQueueBinding(){
        return BindingBuilder.bind(delayQueue()).to(exchangeKillTopic()).with("#.delay").noargs();
    }
    // 绑定死信队列到交换机
    @Bean
    public Binding deadQueueBinding(){
        return BindingBuilder.bind(deadQueue()).to(exchangeKillTopic()).with("#.dead").noargs();
    }

    //定义RabbitTemplate 指定 JSON转换器
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        //1.把要发送的消息内容 ，交换机，rontkey等都保存下来到Mysql
        //2.后续可以用来重写发送消息，甚至可以使用一个定时任务不停的重试，可以甚至一个最大重试次数
        //设置消息回调
        rabbitTemplate.setMandatory(true);

        return rabbitTemplate;
    }


    //定义 监听器的工厂 ，定义JSON的转换器
    @Bean("rabbitListenerContainerFactory")
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setConcurrentConsumers(3);
        factory.setMaxConcurrentConsumers(10);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        factory.setPrefetchCount(1);
        return factory;
    }

}
